package com.alex.core.oss;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.ddcx.config.CoreProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 *
 * @author xc
 * @date 2019/6/13
 */
@Service
public class AliossUtls {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OSSClient client;

    @Autowired
    private CoreProperties coreProperties;

//    public static void main(String args[]){
//        String a = "1.jpg";
//        AliossUtls aliossUtls = new AliossUtls();
//        System.out.println(aliossUtls.getContentType(a));
//    }
    /**
     * 向阿里云的OSS存储中存储文件
     * <p>
     * bucket名称
     *
     * @param diskName 上传文件的目录 --bucket下文件的路径
     * @return String 唯一MD5数字签名
     */
    public String uploadFileBase64OSS(String bucketName,String fileBase64, String diskName, String fileName) {
        String resultStr = null;
        try {

            InputStream is = baseToInputStream(fileBase64);
            // 创建上传Object的Metadata
            ObjectMetadata metadata = getObjectMetadata(fileName, is);
            // 上传文件
            if (diskName.startsWith("/")) {
                diskName = diskName.substring(1, diskName.length());
            }
            PutObjectResult putResult = client.putObject(bucketName, diskName + "/" + fileName, is, metadata);
            // 解析结果
            return "http://"+bucketName+"."+coreProperties.getOssEndpoint()+"/"+ diskName+"/"+ fileName;
        } catch (Exception e) {
            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return null;
    }

    ObjectMetadata getObjectMetadata(String fileName, InputStream is) throws IOException {
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentLength(is.available());
        metadata.setCacheControl("no-cache");
        metadata.setHeader("Pragma", "no-cache");
        metadata.setContentEncoding("utf-8");
        metadata.setContentType(getContentType(fileName));
        return metadata;
    }

    /**
     * springMvc上传文件
     * @param file
     * @param fileName
     * @param diskName
     * @return
     */
    public String uploadMvcFile(MultipartFile file,String bucketName, String fileName, String diskName) {
        if (file != null) {
            //转base64
            BASE64Encoder encoder = new BASE64Encoder();
            try {
                String data = encoder.encode(file.getBytes());
                return this.uploadFileBase64OSS(bucketName,data, diskName, fileName);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
           return null;
        }
        return null;
    }



    /**
     * 向changchong buketName里面存储中存储文件,返回外网访问路径
     *
     * @param diskName 上传文件的目录 --bucket下文件的路径
     * @return String 唯一MD5数字签名
     */
    public String uploadOSSFill(String bucketName,InputStream is, String fileName, long fileSize, String diskName) {
        String resultStr = null;
        try {
            // 创建上传Object的Metadata
            ObjectMetadata metadata = getObjectMetadata(fileName, is);
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            // 上传文件
            PutObjectResult putResult = client.putObject(bucketName ,diskName + fileName, is, metadata);
            // 解析结果
            return "http://"+bucketName+"."+coreProperties.getOssEndpoint()+"/"+ diskName+"/"+ fileName;
        } catch (Exception e) {
            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return null;
    }

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     *
     * @param fileName 文件名
     * @return 文件的contentType
     */
    public String getContentType(String fileName) {
        String fileExtension = fileName.substring(fileName.lastIndexOf(".")+1);
        if ("bmp".equalsIgnoreCase(fileExtension)) {
            return "image/bmp";
        }
        if ("gif".equalsIgnoreCase(fileExtension)) {
            return "image/gif";
        }
        if ("jpeg".equalsIgnoreCase(fileExtension) || "jpg".equalsIgnoreCase(fileExtension)
                || "png".equalsIgnoreCase(fileExtension)) {
            return "image/jpeg";
        }
        if ("html".equalsIgnoreCase(fileExtension)) {
            return "text/html";
        }
        if ("txt".equalsIgnoreCase(fileExtension)) {
            return "text/plain";
        }
        if ("vsd".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.visio";
        }
        if ("ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if ("doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
            return "application/msword";
        }
        if ("xml".equalsIgnoreCase(fileExtension)) {
            return "text/xml";
        }
        if (".apk".equalsIgnoreCase(fileExtension)) {
            return "application/octet-stream";
        }
        if (".zip".equalsIgnoreCase(fileExtension)) {
            return "application/octet-stream";
        }
        return "text/html";
    }

    /**
     * 根据key获取OSS服务器上的文件输入流
     * <p>
     * bucket名称
     *
     * @param diskName 文件路径
     * @param key      Bucket下的文件的路径名+文件名
     */
    public final InputStream getOSS2InputStream(String bucketName,String diskName, String key) {
        OSSObject ossObj = client.getObject(bucketName, diskName + key);
        return ossObj.getObjectContent();
    }

    /**
     * 根据key删除OSS服务器上的文件
     * <p>
     * bucket名称
     *
     * @param diskName 文件路径
     * @param key      Bucket下的文件的路径名+文件名
     */
    public void deleteFile(String bucketName,String diskName, String key) {
        boolean exist = client.doesObjectExist(bucketName, diskName+"/"+key);
        if (!exist) {
            logger.error("文件不存在,filePath={}", key);
            return;
        }
        client.deleteObject(bucketName, diskName + key);
        logger.info("删除" + bucketName + "下的文件" + diskName + key + "成功");
    }

    /**
     * base64转inputStream
     *
     * @param base64string
     * @return <p>
     * author: <views href="mailto:maochaowu@ancun.com">Maochaowu</views><br>
     * create at: 2014年4月16日上午12:34:54
     */
    private InputStream baseToInputStream(String base64string) {
        ByteArrayInputStream stream = null;
        try {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes1 = decoder.decodeBuffer(base64string);
            stream = new ByteArrayInputStream(bytes1);
        } catch (Exception e) {
            logger.error("base64转inputStream异常：" + e.getMessage());
        }
        return stream;
    }
}
